package main

import "fmt"

// ==========分支结构==========
// switch语句用于基于不同条件执行不同动作, 每一个case分支都是唯一的, 从上到下逐一测试, 直到匹配为止
// switch的执行流程是, 先执行表达式得到值, 然后和case的表达式进行比较, 如果相等则匹配到, 执行该case里对应的语句块, 然后结束switch控制流程
// 如果switch的值没有和任何case的表达式匹配成功, 则执行default里面的语句块, 执行后, 退出switch控制流程
// golang的case后面的表达式可以有多个, 使用逗号隔开
// golang的case里不需要加break

/*
switch 表达式 {
case 表达式1, 表达式2:
	语句块1
case 表达式3, 表达式4:
	语句块2
...
default:
	语句块
}
*/

func simple() int {
	return 1
}

func main() {
	// 程序接收一个字符, 比如a、b、c、d, a表示星期一, b表示星期二..., 根据用户输入显示相应的信息
	var char byte
	fmt.Println("请输入一个字符:")
	_, _ = fmt.Scanf("%c", &char)
	switch char {
	case 'a':
		fmt.Println("今天星期一, 猴子穿新衣")
	case 'b':
		fmt.Println("今天星期二, 猴子当小二")
	case 'c':
		fmt.Println("今天星期三, 猴子爬雪山")
	case 'd':
		fmt.Println("今天星期四, 猴子去考试")
	case 'e':
		fmt.Println("今天星期五, 猴子去跳舞")
	case 'f':
		fmt.Println("今天星期六, 猴子去溜溜")
	case 'g':
		fmt.Println("今天星期日, 猴子过生日")
	default:
		fmt.Println("输入有误, 请重新输入")
	}

	// switch后面可以是一个常量
	switch 1 {
	case 1, 2:
		fmt.Println(1, 2)
	case 3, 4:
		fmt.Println(3, 4)
	default:
		fmt.Println(5)
	}

	// switch后面可以是一个有返回值的函数
	switch simple() {
	case 1:
		fmt.Println(1)
	default:
		fmt.Println(2)
	}

	// case后的表达式如果是常量值, 则要求不能重复; 如果是变量, 则可以使用
	var a int32
	var b int32 = 3
	switch a {
	case 1, 2, 3:
		fmt.Println(123)
	case b:
		fmt.Println('b')
	}

	// switch后也可以不带表达式, 类似if-else来使用
	var age int
	switch {
	case age == 10, age == 11:
		fmt.Println("age==10")
	case age == 20:
		fmt.Println("age==20")
	default:
		fmt.Println("no matched")
	}

	// case中也可以对age的范围判断
	var score int
	switch {
	case score > 90:
		fmt.Println("优秀")
	case score >= 70 && score <= 90:
		fmt.Println("良")
	case score >= 60 && score < 70:
		fmt.Println("及格")
	default:
		fmt.Println("不及格")
	}

	// switch后也可以直接声明/定义一个变量, 分号结束, 不推荐
	switch grade := 90; {
	case grade > 90:
		fmt.Println("优秀~")
	case grade >= 70:
		fmt.Println("良~")
	case grade >= 60 && grade < 70:
		fmt.Println("及格~")
	default:
		fmt.Println("不及格~")
	}

	// switch穿透fallthrough
	var num = 10
	switch num {
	case 10:
		fmt.Println("ok1")
		fallthrough // 只能穿透一层, 输出ok1也输出ok2
	case 20:
		fmt.Println("ok2")
	case 30:
		fmt.Println("ok3")
	default:
		fmt.Println("no matched")
	}
}
